#ifndef ENTITY_GRID
#define ENTITY_GRID

#include <SFML/System.hpp>
#include <map>
#include <vector>
#include <deque>

#define BOXSIZE 400

class EntityBox
{
public:
    EntityBox();
	EntityBox(int size);

    std::deque<int> getEntityDeque(int type) const;
    void addEntity(int type, int id);
    void deleteEntity(int type, int id);
    void clearEntities(int type);
    void clearAllEntities();

protected:
	std::vector<std::deque<int> > mpt_deques;

};

class EntityGrid
{
public:
    EntityGrid() {}
    EntityGrid(int X, int Y, int sizeBox = 1);
    EntityGrid(const sf::Vector2i& size, int sizeBox = 1);

    void addEntity(int type, int id, const sf::Vector2f& position);
    void deleteEntity(int type, int id);
    std::deque<int> getNeighbourhoodAt(int type, const sf::Vector2f& position) const;

    void deleteNeighbourhood(int type, const sf::Vector2f& position);

    void resize(const sf::Vector2i& size); //Delete all entities

protected:
    sf::Vector2i mpt_size;
    std::map<int, int> mpt_entitiesToBoxes;
    std::vector<EntityBox> mpt_boxes;

private: 
	void deleteBox(int box, int type);

};

class EntityMap
{
public:
    EntityMap() {}
    EntityMap(int X, int Y);
    EntityMap(const sf::Vector2i& size);

    void addEntity(int id, const sf::Vector2i& position);
    int getEntity(const sf::Vector2i& position) const;
	std::vector<int> getNeighbourhoodAt(const sf::Vector2i& position, int rayX, int rayY);
    void clearEntities();
	void deleteEntity(const sf::Vector2i& position);
	void deleteEntity(int id);

    void resize(const sf::Vector2i& size); //Delete all entities

protected:
    std::vector<int> mpt_entities;
	std::map<int, sf::Vector2i> mpt_entityIDtoPos;
    sf::Vector2i mpt_size;
};

#endif

